// 只读类型(Readonly<T>)
// 定义：

// interface Person {
//     name: string
//     age: number
// }
// type Readonly_Demo<T>={

//     // readonly 属性变成只读
//     //  P -> "name", "age"; T->Person ； T[P]->分别为string,number 
//     readonly [P in keyof T]:T[P]  // 注意T[P] 代表的是类型！  Person['name'], Person['number'] 其实就是string,number
// }
// type nameType=  Person['name']
// type ageType=  Person['age']


// //  person其实是一个实例，满足所有属性必须在Person存在，同时属性的类型=接口Person中对应属性的类型 
// const person: Readonly_Demo<Person> = {
//     name: 'Lucy', 
//     age: 22
// }
 
// // 会报错：Cannot assign to 'name' because it is a read-only property
// person.name = 'Lily'



// 可选类型(Partial<T>)
// 用于将 T 类型的所有属性设置为可选状态，首先通过 keyof T，取出类型 T 的所有属性， 然后通过 in 操作符进行遍历，最后在属性后加上 ?，将属性变为可选属性。

// 定义：

// type Partial<T> = {
//     [P in keyof T]?: T[P];
// }
// 复制代码
// 用法：

// interface Person {
//     name: string
//     age: number
// }
 
// // 会报错：Type '{}' is missing the following properties from type 'Person': name, age
// // let person0: Person = {}
 
// // 使用 Partial 映射后返回的新类型，name 和 age 都变成了可选属性
// let person: Partial<Person> = {}
 
// person = { name: 'pengzu', age: 800 }
 
// person = { name: 'z' }
 
// person = { age: 18 }
// person = { }


// 必选类型(Required<T>)
// 和 Partial 的作用相反

// 用于将 T 类型的所有属性设置为必选状态，首先通过 keyof T，取出类型 T 的所有属性， 然后通过 in 操作符进行遍历，最后在属性后的 ? 前加上 -，将属性变为必选属性。

// 定义：

// type Required<T> = {
//     [P in keyof T]-?: T[P];
// }
// 复制代码
// 使用：

// interface Person {
//     name?: string
//     age?: number
// }
 
// 使用 Required 映射后返回的新类型，name 和 age 都变成了必选属性
// 会报错：Type '{}' is missing the following properties from type 'Required<Person>': name, age
// let person: Required<Person> = {}

// 提取属性(Pick<T>)
// 定义：

// type Pick<T, K extends keyof T> = {
//     [P in K]: T[P];
// }
// 复制代码
// 从 T 类型中提取部分属性，作为新的返回类型。

// 使用：比如我们在发送网络请求时，只需要传递类型中的部分属性，就可以通过 Pick 来实现。

// interface Goods {
//     type: string
//     goodsName: string
//     price: number
// }
 
// // 作为网络请求参数，只需要 goodsName 和 price 就可以
// type RequestGoodsParams = Pick<Goods, 'goodsName' | 'price'>
// // 返回类型：
// // type RequestGoodsParams = {
// //     goodsName: string;
// //     price: number;
// // }
// const params: RequestGoodsParams = {
//     goodsName: '',
//     price: 10
// }

// interface IStudent{
//     name:string;
//     age:string;
// }

// type PickStudentType<T,P extends keyof T>={

//     [K in P]:T[K]

// }

// let student :PickStudentType<IStudent,'name'>={name:"12"};


// 排除类型(Exclude<T, U>)
// 语法：Exclude<T, U>

// 与 Extract 用法相反，从 T 中剔除可以赋值给 U的类型

// 定义：type Exclude<T, U> = T extends U ? never : T


// // 用法：

// type T000 = Exclude<"a" | "b" | "c" | "d", "a" | "c" | "f">;  // "b" | "d"
// type T001 = Exclude<"a" | "c", "a" | "c" | "f">;  // never
 
// type T002 = Exclude<string | number | (() => void), Function>;  // string | number


// 摘取类型(Extract<T, U>)
// 语法：Extract<T, U>

// 提取 T 中可以 赋值 给 U 的类型

// 定义：type Extract<T, U> = T extends U ? T : never;

// 用法：

// type T01 = Extract<"a" | "b" | "c" | "d", "a" | "c" | "f">;  // "a" | "c"
 
// type T02 = Extract<string | number | (() => void), Function>;  // () => void




// type a="a" | "b" | "c" | "d"
// type b="a" | "c" | "f"


interface IStudent0{
    name:string;
    age:number;
    class:string;
}

//抽取name age 属性

// type type01=Pick<IStudent,"name"|"age">;
// let student01:type01={name:"szq",age:22}


// type 抽取类型="name"|"age"
// type type1=Pick<IStudent,抽取类型>;
// let student:type1={name:"szq",age:22}

// type 抽取类型=Extract<keyof IStudent,"name"|"age">
// type type1=Pick<IStudent,抽取类型>;
// let student:type1={name:"szq",age:22}

// type 抽取类型=Exclude<keyof IStudent,"class">
// type type1=Pick<IStudent,抽取类型>;
// let student:type1={name:"szq",age:22}

// type type1=Pick<IStudent,Exclude<keyof IStudent,"class">>;
// let student:type1={name:"szq",age:22}

type type1=Omit<IStudent0,"class">
let student02:type1={name:"szq",age:22}

